﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Script.Serialization;

namespace FClient
{
    public class YahooApi
    {
        const string URL_OAUTH_DIRECT = "https://login.yahoo.com/WSLogin/V1/get_auth_token";
        const string URL_OAUTH_ACCESS_TOKEN = "https://api.login.yahoo.com/oauth/v2/get_token";
        const string URL_YM_SESSION = "http://developer.messenger.yahooapis.com/v1/session";
        const string URL_YM_PRESENCE = "http://developer.messenger.yahooapis.com/v1/presence";
        const string URL_YM_CONTACT = "http://developer.messenger.yahooapis.com/v1/contacts";
        const string URL_YM_MESSAGE = "http://rcore1.messenger.yahooapis.com/v1/message/yahoo/{{USER}}";
        const string URL_YM_NOTIFICATION = "http://developer.messenger.yahooapis.com/v1/notifications";
        const string URL_YM_BUDDYREQUEST = "http://developer.messenger.yahooapis.com/v1/buddyrequest/yahoo/{{USER}}";
        const string URL_YM_GROUP = "http://developer.messenger.yahooapis.com/v1/group/{{GROUP}}/contact/yahoo/{{USER}}";
        protected string _oauth;
        protected Hashtable _token;
        protected Hashtable _ym;
        protected string _config;
        protected string _error;

        public bool includeheader = false;
        public bool debug = false;

        string _UserName;
        string _PassWord;
        string _Key = "dj0yJmk9cVQxNjg1WXVTcVkzJmQ9WVdrOVduRkhjbGd4TjJzbWNHbzlNVGd6TVRnNU1EQTJNZy0tJnM9Y29uc3VtZXJzZWNyZXQmeD1mMg--";
        string _KeySecret = "d0a0e98e8b58cae95f704b024846df7f3c817445";

        public YahooApi() { }
        public YahooApi(string username, string password)
        {
            _UserName = username;
            _PassWord = password;
            _token = new Hashtable();
            _ym = new Hashtable();
        }

        public bool fetch_request_token()
        {
            string url = URL_OAUTH_DIRECT;
            url += ("?login=" + _UserName);
            url += "&passwd=" + this._PassWord;
            url += "&oauth_consumer_key=" + _Key;
            string result = this.HttpGet(url);

            if (result.IndexOf("RequestToken") < 0)
                return false;
            result = result.Replace("RequestToken=", "");
            _token.Add("request", result);

            return true;
        }

        public bool GetToken()
        {
            string url = URL_OAUTH_ACCESS_TOKEN;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26";
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + _token["request"];
            url += "&oauth_version=1.0";

            string result = this.HttpGet(url);

            if (result.IndexOf("oauth_token") < 0)
            {
                _error = result;
                return false;
            }
            string[] listRe = result.Split('&');
            Hashtable Accesstoken = new Hashtable();
            foreach (string item in listRe)
            {
                string[] splitstring = item.Split('=');
                Accesstoken.Add(splitstring[0], splitstring[1]);
            }
            _token.Add("access", Accesstoken);
            return true;
        }

        public bool fetch_crumb()
        {
            string url = URL_YM_SESSION;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";

            HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
            req.Method = "GET";
            req.ContentType = "application/json; charset=utf-8";

            string result = null;
            using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
            {
                using (var reader = new StreamReader(resp.GetResponseStream()))
                {
                    result = reader.ReadToEnd();
                }
            }

            return true;
        }

        public Hashtable signon(string state, string status)
        {
            string url = URL_YM_SESSION;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";
            url += "&notifyServerToken=1";

            string postdata = "{\"presenceState\" : " + state + ",\"presenceMessage\" : \"" + status + "\"}";

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";

            request.ContentType = "application/json; charset=utf-8";

            using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
            {
                sw.Write(postdata);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string res = "";
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                res = sr.ReadToEnd();
            }

            if (res.IndexOf("sessionId") < 0)
                return null;
            JavaScriptSerializer js = new JavaScriptSerializer();
            dynamic Objectjson = js.DeserializeObject(res);

            _ym.Add("signon", Objectjson);
            Hashtable data = new Hashtable();
            data.Add("oauth_token_secret", ((Hashtable)_token["access"])["oauth_token_secret"]);
            data.Add("oauth_token", ((Hashtable)_token["access"])["oauth_token"]);
            data.Add("sessionId", ((Dictionary<string, object>)_ym["signon"])["sessionId"]);
            return data;
        }

        public bool signoff()
        {
            string url = URL_YM_SESSION;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";
            url += "&notifyServerToken=1";
            url += "&sid=" + ((Hashtable)_ym["signon"])["sessionId"];

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "DELETE";
            request.ContentType = "application/json; charset=utf-8";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            return true;
        }
        public bool change_presence(string status = "", int state = 0)
        {
            string url = URL_YM_PRESENCE;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + DateTime.Now.Millisecond;
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";

            url += "&sid=" + ((Dictionary<string, object>)_ym["signon"])["sessionId"];

            string postdata = "{\"presenceState\" : " + state + ",\"presenceMessage\" : \"" + status + "\"}";

            HttpWebRequest request = WebRequest.Create(url)
                                   as HttpWebRequest;
            request.Method = "PUT";
            request.ContentType = "application/json; charset=utf-8";

            using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
            {
                sw.Write(postdata);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            return true;
        }

        public bool send_message(string user, string message)
        {
            string url = URL_YM_MESSAGE;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";

            url += "&sid=" + ((Dictionary<string, object>)_ym["signon"])["sessionId"];
            url = url.Replace("{{USER}}", user);

            string postdata = "{\"message\" : \"" + message + " \"}";

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/json; charset=utf-8";

            using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
            {
                sw.Write(postdata);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            return true;
        }

        public bool SendMessage(string user, string message, string oauth_token_secret, string oauth_token, string sessionId)
        {
            string url = URL_YM_MESSAGE;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + oauth_token_secret;
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + oauth_token;
            url += "&oauth_version=1.0";
            url += "&sid=" + sessionId;

            url = url.Replace("{{USER}}", user);

            string postdata = "{\"message\" : \"" + message + " \"}";

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";

            request.ContentType = "application/json; charset=utf-8";

            using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
            {
                sw.Write(postdata);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            return true;
        }

        public string GetContact(string uri, string oauth_token_secret, string oauth_token, string sessionId)
        {
            string url = "http://" + uri;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + oauth_token_secret;
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + oauth_token;
            url += "&oauth_version=1.0";

            url += "&sid=" + sessionId;

            string result = this.HttpGet(url);

            return result;
        }

        public long gettime()
        {
            return (long)DateTime.UtcNow.Ticks;
        }

        public bool fetch_contact_list()
        {
            string url = URL_YM_CONTACT;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";

            url += "&sid=" + ((Dictionary<string, object>)_ym["signon"])["sessionId"];
            url += "&fields=%2Bpresence";

            string list = this.HttpGet(url);

            JavaScriptSerializer js = new JavaScriptSerializer();
            dynamic Objectjson = js.DeserializeObject(list);

            return true;
        }

        public string FetchContactList(string oauth_token_secret, string oauth_token, string sessionId)
        {
            string url = URL_YM_CONTACT;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + oauth_token_secret;
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + oauth_token;
            url += "&oauth_version=1.0";

            url += "&sid=" + sessionId;
            url += "&fields=%2Bpresence";

            string list = this.HttpGet(url);

            return list;
        }

        public bool fetch_notification(int seq = 0)
        {
            string url = URL_YM_NOTIFICATION;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + ((Hashtable)_token["access"])["oauth_token_secret"];
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + DateTime.Now.Millisecond;
            url += "&oauth_token=" + ((Hashtable)_token["access"])["oauth_token"];
            url += "&oauth_version=1.0";
            url += "&sid=" + ((Dictionary<string, object>)_ym["signon"])["sessionId"];
            url += "&seq=" + seq;
            url += "&count=100";

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";

            request.ContentType = "application/json; charset=utf-8";

            string result = null;
            using (HttpWebResponse resp = request.GetResponse() as HttpWebResponse)
            {
                using (var reader = new StreamReader(resp.GetResponseStream()))
                {
                    result = reader.ReadToEnd();
                }
            }

            JavaScriptSerializer js = new JavaScriptSerializer();
            dynamic Objectjson = js.DeserializeObject(result);

            return true;
        }

        public string FetchNotification(string oauth_token_secret, string oauth_token, string sessionId, int seq = 0)
        {
            string url = URL_YM_NOTIFICATION;
            url += "?oauth_consumer_key=" + _Key;
            url += "&oauth_nonce=" + (new Random()).Next();
            url += "&oauth_signature=" + _KeySecret + "%26" + oauth_token_secret;
            url += "&oauth_signature_method=PLAINTEXT";
            url += "&oauth_timestamp=" + gettime();
            url += "&oauth_token=" + oauth_token;
            url += "&oauth_version=1.0";
            url += "&sid=" + sessionId;
            url += "&seq=" + seq;
            url += "&count=100";

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";

            request.ContentType = "application/json; charset=utf-8";

            string result = null;
            using (HttpWebResponse resp = request.GetResponse() as HttpWebResponse)
            {
                using (var reader = new StreamReader(resp.GetResponseStream()))
                {
                    result = reader.ReadToEnd();
                }
            }

            return result;
        }

        public string HttpGet(string url)
        {
            try
            {
                HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
                req.Method = "GET";

                string result = null;
                using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
                {
                    using (var reader = new StreamReader(resp.GetResponseStream()))
                    {
                        result = reader.ReadToEnd();
                    }
                }
                return result;
            }
            catch (Exception e)
            {
                return "";
            }
        }

        public void Login(string username, string password)
        {
            string url = "https://login.yahoo.com/WSLogin/V1/get_auth_token?&login=" + username + "&passwd=" + password + "&oauth_consumer_key=" + _Key;
            string token = HttpGet(url);
        }

        public void createSession()
        {
            HttpWebRequest req = WebRequest.Create("/v1/session") as HttpWebRequest;
            req.Method = "POST";
            req.Host = "developer.messenger.yahooapis.com";
            req.ContentType = "application/json;charset=utf-8";

            string result = null;
            using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
            {
                using (var reader = new StreamReader(resp.GetResponseStream()))
                {
                    result = reader.ReadToEnd();
                }
            }
        }
    }
}